package org.sso.common.cookie;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.sso.common.cons.Const;
import org.sso.common.cons.ParamConst;
import org.sso.common.domian.Ticket;
import org.sso.common.domian.Token;
import org.sso.common.domian.TokenBase;
import org.sso.common.encrypt.AES;
import org.sso.common.encrypt.SSOEncrypt;
import org.sso.common.util.GsonHelper;
import org.sso.common.util.IpHelper;

import com.google.gson.reflect.TypeToken;

public class TokenHelper extends CookieHelper {
	private static Logger logger = Logger.getLogger(TokenHelper.class);

	public static Token getToken(HttpServletRequest request) {
		String jsonTk = getJsonToken(request, AES.getInstance(), Const.cookieName);
		if (StringUtils.isBlank(jsonTk)) {
			return null;
		}
		Token tk = GsonHelper.toObj(jsonTk, new TypeToken<Token>() {
		});
		return (Token) checkIp(request, tk);
	}

	public static Ticket getTicket(HttpServletRequest request) {
		String jsonTk = getJsonToken(request, AES.getInstance(), Const.ticket_cookiename);
		if (StringUtils.isBlank(jsonTk)) {
			return null;
		}
		Ticket tk = GsonHelper.toObj(jsonTk, new TypeToken<Ticket>() {
		});
		return (Ticket) checkIp(request, tk);
	}

	/**
	 * <p>
	 * 校验Token IP 与登录 IP 是否一致
	 * </p>
	 * 
	 * @param request
	 * @param token
	 *            登录票据
	 * @return Token {@link Token}
	 */
	public static TokenBase checkIp(HttpServletRequest request, TokenBase token) {
		String ip = IpHelper.getIpAddr(request);
		if (token != null && ip != null && !ip.equals(token.getIp())) {
			/**
			 * 检查 IP 与登录IP 不一致返回 null
			 */
			logger.error("ip校验不一致");
			return null;
		}
		return token;
	}

	/**
	 * <p>
	 * 获取当前请求 JsonToken
	 * </p>
	 * 
	 * @param request
	 * @param encrypt
	 *            对称加密算法类
	 * @param cookieName
	 *            Cookie名称
	 * @return String 当前Token的json格式值
	 */
	public static String getJsonToken(HttpServletRequest request, SSOEncrypt encrypt, String cookieName) {
		Cookie uid = CookieHelper.findCookieByName(request, cookieName);
		if (uid != null) {
			String jsonToken = uid.getValue();
			String[] tokenAttr = new String[2];
			try {
				jsonToken = encrypt.decrypt(jsonToken, ParamConst.AES_KEY);
				tokenAttr = jsonToken.split(Const.CUT_SYMBOL);
			} catch (Exception e) {
				logger.error("AES解密出错");
			}
			return tokenAttr[0];
		}
		return null;
	}

	/**
	 * <p>
	 * 生成跨域回复票据
	 * </p>
	 * 
	 * @param authToken
	 *            跨域信任 Token
	 * @param userId
	 *            用户ID
	 * @param askTxt
	 *            询问密文
	 * @return AuthToken {@link AuthToken}
	 */
	public static Ticket replyCiphertext(HttpServletRequest request, String askData) {
		String str = null;
		try {
			str = AES.getInstance().decrypt(askData, ParamConst.AES_KEY);
		} catch (Exception e) {
			logger.info("replyCiphertext AES decrypt error.\n" + e.toString());
		}
		if (str != null) {
			/*
			 * <p> 使用业务系统公钥验证签名 </p> <p> 验证 IP 地址是否合法 </p>
			 */
			Ticket at = GsonHelper.toObj(str, new TypeToken<Ticket>() {
			});
			if (checkIp(request, at) != null) {
				return at;
			}
		}
		return null;
	}

	public static void main(String[] args) throws Exception {
		String secret = AES.getInstance().encrypt("123jc是天才", ParamConst.AES_KEY);
		// String secret2 = AES.getInstance().encrypt("123jc是天才2",
		// Const.Secretkey);
		System.out.println(secret);
		System.out.println(AES.getInstance().decryptAES(secret));
	}
}
